home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 2.iso / textproc / _j1 / tex2rtf / src / tex2rtf.cc < prev    next >
C/C++ Source or Header  |  1993-10-25  |  14KB  |  569 lines

  1. /*
  2.  * File:     tex2rtf.cc
  3.  * Purpose:  Converts Latex to RTF
  4.  *
  5.  *                       wxWindows 1.50
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                        Date: 7-9-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <wx.h>
  30. #include <wx_help.h>
  31. #include <ctype.h>
  32. #include "tex2any.h"
  33. #include "tex2rtf.h"
  34. #include "rtfutils.h"
  35.  
  36. TexChunk *currentSection = NULL;
  37. TexChunk *currentMember = NULL;
  38. Bool startedSections = FALSE;
  39. char *contentsString = NULL;
  40. Bool suppressNameDecoration = FALSE;
  41. Bool winHelp = FALSE;  // Output in Windows Help format if TRUE, linear otherwise
  42. Bool isInteractive = FALSE;
  43. Bool runTwice = FALSE;
  44. Bool convertMode = TEX_RTF;
  45. wxHelpInstance *HelpInstance = NULL;
  46.  
  47. FILE *Contents = NULL;   // Contents page
  48. FILE *Chapters = NULL;   // Chapters (WinHelp RTF) or rest of file (linear RTF)
  49. FILE *Sections = NULL;
  50. FILE *Subsections = NULL;
  51. FILE *Subsubsections = NULL;
  52.  
  53. char *InputFile = NULL;
  54. char *OutputFile = NULL;
  55. char *MacroFile = copystring("tex2rtf.ini");
  56.  
  57. char FileRoot[300];
  58. char ContentsName[300];    // Contents page from last time around
  59. char TmpContentsName[300]; // Current contents page
  60. char RefName[300];         // Reference file name
  61.  
  62. wxMenuBar *menuBar = NULL;
  63. MyFrame *frame = NULL;
  64.  
  65. Bool Go(void);
  66.  
  67. // This statement initializes the whole application and calls OnInit
  68. MyApp myApp;
  69.  
  70. // `Main program' equivalent, creating windows and returning main app frame
  71. wxFrame *MyApp::OnInit(void)
  72. {
  73.   // Use default list of macros defined in tex2any.cc
  74.   DefineDefaultMacros();
  75.   AddMacroDef("hardy", 0);
  76.  
  77.   TexInitialize();
  78.  
  79.   int n = 1;
  80.   
  81.   // Read input/output files
  82.   if (argc > 1)
  83.   {
  84.     if (argv[1][0] != '-')
  85.     {
  86.       InputFile = argv[1];
  87.       n ++;
  88.  
  89.       if (argc > 2)
  90.       {
  91.         if (argv[2][0] != '-')
  92.         OutputFile = argv[2];
  93.         n ++;
  94.       }
  95.     }
  96.   }
  97.  
  98.   for (int i = n; i < argc;)
  99.   {
  100.     if (strcmp(argv[i], "-winhelp") == 0)
  101.     {
  102.       i ++;
  103.       convertMode = TEX_RTF;
  104.       winHelp = TRUE;
  105.     }
  106.     else if (strcmp(argv[i], "-interactive") == 0)
  107.     {
  108.       i ++;
  109.       isInteractive = TRUE;
  110.     }
  111.     else if (strcmp(argv[i], "-rtf") == 0)
  112.     {
  113.       i ++;
  114.       convertMode = TEX_RTF;
  115.     }
  116.     else if (strcmp(argv[i], "-html") == 0)
  117.     {
  118.       i ++;
  119.       convertMode = TEX_HTML;
  120.     }
  121.     else if (strcmp(argv[i], "-xlp") == 0)
  122.     {
  123.       i ++;
  124.       convertMode = TEX_XLP;
  125.     }
  126.     else if (strcmp(argv[i], "-twice") == 0)
  127.     {
  128.       i ++;
  129.       runTwice = TRUE;
  130.     }
  131.     else if (strcmp(argv[i], "-macros") == 0)
  132.     {
  133.       i ++;
  134.       if (i < argc)
  135.       {
  136.         MacroFile = copystring(argv[i]);
  137.         i ++;
  138.       }
  139.     }
  140.     else
  141.     {
  142.       char buf[100];
  143.       sprintf(buf, "Invalid switch %s.\n", argv[i]);
  144.       OnError(buf);
  145.       i++;
  146.     }
  147.   }
  148.  
  149.   if (!InputFile && !OutputFile)
  150.     isInteractive = TRUE;
  151.  
  152.   if (isInteractive)
  153.   {
  154.     // Create the main frame window
  155.     frame = new MyFrame(NULL, "Tex2RTF", 0, 0, 400, 300);
  156.     frame->CreateStatusLine(2);
  157.     char buf[200];
  158.     strcpy(buf, "In ");
  159.  
  160.     if (winHelp)
  161.       strcat(buf, "linear ");
  162.     if (convertMode == TEX_RTF) strcat(buf, "RTF");
  163.     else if (convertMode == TEX_HTML) strcat(buf, "HTML");
  164.     else if (convertMode == TEX_XLP) strcat(buf, "XLP");
  165.     strcat(buf, " mode.");
  166.     frame->SetStatusText(buf, 1);
  167.  
  168.     // Make a menubar
  169.     wxMenu *file_menu = new wxMenu;
  170.     file_menu->Append(TEX_GO, "&Go",                        "Run converter");
  171.     file_menu->Append(TEX_SET_INPUT, "Set &Input File",     "Set the LaTeX input file");
  172.     file_menu->Append(TEX_SET_OUTPUT, "Set &Output File",   "Set the output file");
  173.     file_menu->Append(TEX_VIEW_LATEX, "View &LaTeX File",   "View the LaTeX input file");
  174.     file_menu->Append(TEX_VIEW_OUTPUT, "View Output &File", "View output file");
  175.     file_menu->Append(TEX_QUIT, "&Exit",                    "Exit Tex2RTF");
  176.  
  177.     wxMenu *macro_menu = new wxMenu;
  178.  
  179.     macro_menu->Append(TEX_LOAD_CUSTOM_MACROS, "&Load Custom Macros", "Load custom LaTeX macro file");
  180.     macro_menu->Append(TEX_VIEW_CUSTOM_MACROS, "View &Custom Macros", "View custom LaTeX macros");
  181.  
  182.     wxMenu *mode_menu = new wxMenu;
  183.  
  184.     mode_menu->Append(TEX_MODE_RTF, "Output linear &RTF",   "Wordprocessor-compatible RTF");
  185.     mode_menu->Append(TEX_MODE_WINHELP, "Output &WinHelp RTF", "WinHelp-compatible RTF");
  186.     mode_menu->Append(TEX_MODE_HTML, "Output &HTML",        "HTML World Wide Web hypertext file");
  187.     mode_menu->Append(TEX_MODE_XLP, "Output &XLP",          "wxHelp hypertext help file");
  188.  
  189.     wxMenu *help_menu = new wxMenu;
  190.  
  191.     help_menu->Append(TEX_HELP, "&Help", "Tex2RTF Contents Page");
  192.     help_menu->Append(TEX_ABOUT, "&About Tex2RTF", "About Tex2RTF");
  193.  
  194.     menuBar = new wxMenuBar;
  195.     menuBar->Append(file_menu, "&File");
  196.     menuBar->Append(macro_menu, "&Macros");
  197.     menuBar->Append(mode_menu, "&Conversion Mode");
  198.     menuBar->Append(help_menu, "&Help");
  199.  
  200.     frame->SetMenuBar(menuBar);
  201.     frame->textWindow = new wxTextWindow(frame);
  202.  
  203.     (*frame->textWindow) << "Welcome to Julian Smart's LaTeX to RTF converter.\n\n";
  204.     
  205.     (*frame->textWindow) << "Usage: tex2rtf [input] [output] [switches]\n\n";
  206.     (*frame->textWindow) << "where valid switches are\n";
  207.     (*frame->textWindow) << "    -interactive\n";
  208.     (*frame->textWindow) << "    -twice\n";
  209.     (*frame->textWindow) << "    -macros <filename>\n";
  210.     (*frame->textWindow) << "    -winhelp\n";
  211.     (*frame->textWindow) << "    -rtf\n";
  212.     (*frame->textWindow) << "    -html\n";
  213.     (*frame->textWindow) << "    -xlp\n\n";
  214.  
  215.     HelpInstance = new wxHelpInstance(TRUE);
  216.     HelpInstance->Initialize("tex2rtf");
  217.  
  218.     frame->Show(TRUE);
  219.     return frame;
  220.   }
  221.   else
  222.   {
  223.     Go();
  224.     if (runTwice) Go();
  225.     return NULL;
  226.   }
  227.  
  228.   // Return the main frame window
  229.   return frame;
  230. }
  231.  
  232. // My frame constructor
  233. MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
  234.   wxFrame(frame, title, x, y, w, h)
  235. {}
  236.  
  237. // Intercept menu commands
  238. void MyFrame::OnMenuCommand(int id)
  239. {
  240.   switch (id) {
  241.     case TEX_QUIT:
  242.       delete this;
  243.       break;
  244.     case TEX_GO:
  245.     {
  246.       menuBar->EnableTop(0, FALSE);
  247.       menuBar->EnableTop(1, FALSE);
  248.       menuBar->EnableTop(2, FALSE);
  249.       menuBar->EnableTop(3, FALSE);
  250.       SetStatusText("Working, pass 1...");
  251.       textWindow->Clear();
  252.       wxYield();
  253.       Go();
  254.       if (runTwice)
  255.       {
  256.         SetStatusText("Working, pass 2...");
  257.         wxYield();
  258.         Go();
  259.       }
  260.       if (runTwice)
  261.         SetStatusText("Done, 2 passes.");
  262.       else
  263.         SetStatusText("Done, 1 pass.");
  264.       menuBar->EnableTop(0, TRUE);
  265.       menuBar->EnableTop(1, TRUE);
  266.       menuBar->EnableTop(2, TRUE);
  267.       menuBar->EnableTop(3, TRUE);
  268.       break;
  269.     }
  270.     case TEX_SET_INPUT:
  271.     {
  272.       ChooseInputFile(TRUE);
  273.       break;
  274.     }
  275.     case TEX_SET_OUTPUT:
  276.     {
  277.       ChooseOutputFile(TRUE);
  278.       break;
  279.     }
  280.     case TEX_VIEW_OUTPUT:
  281.     {
  282.       ChooseOutputFile();
  283.       if (OutputFile && FileExists(OutputFile))
  284.       {
  285.         textWindow->LoadFile(OutputFile);
  286.         char buf[300];
  287.         sprintf(buf, "Tex2RTF [%s]", FileNameFromPath(OutputFile));
  288.         frame->SetTitle(buf);
  289.       }
  290.       break;
  291.     }
  292.     case TEX_VIEW_LATEX:
  293.     {
  294.       ChooseInputFile();
  295.       if (InputFile && FileExists(InputFile))
  296.       {
  297.         textWindow->LoadFile(InputFile);
  298.         char buf[300];
  299.         sprintf(buf, "Tex2RTF [%s]", FileNameFromPath(InputFile));
  300.         frame->SetTitle(buf);
  301.       }
  302.       break;
  303.     }
  304.     case TEX_LOAD_CUSTOM_MACROS:
  305.     {
  306.       textWindow->Clear();
  307.       char *s = wxFileSelector("Choose custom macro file", PathOnly(MacroFile), FileNameFromPath(MacroFile), "ini", "*.ini");
  308.       if (s)
  309.       {
  310.         MacroFile = copystring(s);
  311.         ReadCustomMacros(s);
  312.         ShowCustomMacros();
  313.       }
  314.       break;
  315.     }
  316.     case TEX_VIEW_CUSTOM_MACROS:
  317.     {
  318.       textWindow->Clear();
  319.       wxYield();
  320.       ShowCustomMacros();
  321.       break;
  322.     }
  323.     case TEX_MODE_RTF:
  324.     {
  325.       convertMode = TEX_RTF;
  326.       winHelp = FALSE;
  327.       InputFile = NULL;
  328.       OutputFile = NULL;
  329.       SetStatusText("In linear RTF mode.", 1);
  330.       break;
  331.     }
  332.     case TEX_MODE_WINHELP:
  333.     {
  334.       convertMode = TEX_RTF;
  335.       winHelp = TRUE;
  336.       InputFile = NULL;
  337.       OutputFile = NULL;
  338.       SetStatusText("In WinHelp RTF mode.", 1);
  339.       break;
  340.     }
  341.     case TEX_MODE_XLP:
  342.     {
  343.       convertMode = TEX_XLP;
  344.       InputFile = NULL;
  345.       OutputFile = NULL;
  346.       SetStatusText("In XLP mode.", 1);
  347.       break;
  348.     }
  349.     case TEX_MODE_HTML:
  350.     {
  351.       convertMode = TEX_HTML;
  352.       InputFile = NULL;
  353.       OutputFile = NULL;
  354.       SetStatusText("In HTML mode.", 1);
  355.       break;
  356.     }
  357.     case TEX_HELP:
  358.     {
  359.       HelpInstance->LoadFile();
  360.       HelpInstance->DisplayContents();
  361.       break;
  362.     }
  363.     case TEX_ABOUT:
  364.     {
  365.       wxMessageBox("Tex2RTF\nLaTeX to RTF, WinHelp, HTML and wxHelp Conversion\n\n(c) Julian Smart 1993", "About Tex2RTF");
  366.       break;
  367.     }
  368.   }
  369. }
  370.  
  371. void ChooseInputFile(Bool force)
  372. {
  373.   if (force || !InputFile)
  374.   {
  375.     char *s = wxFileSelector("Choose LaTeX input file", PathOnly(InputFile), FileNameFromPath(InputFile), "tex", "*.tex");
  376.     if (s)
  377.     {
  378.       char buf[300];
  379.       InputFile = copystring(s);
  380.       sprintf(buf, "Tex2RTF [%s]", FileNameFromPath(InputFile));
  381.       frame->SetTitle(buf);
  382.       OutputFile = NULL;
  383.     }
  384.   }
  385. }
  386.  
  387. void ChooseOutputFile(Bool force)
  388. {
  389.   char extensionBuf[10];
  390.   char wildBuf[10];
  391.   strcpy(wildBuf, "*.");
  392.   char *path = NULL;
  393.   if (OutputFile)
  394.     path = PathOnly(OutputFile);
  395.   else if (InputFile)
  396.     path = PathOnly(InputFile);
  397.     
  398.   switch (convertMode)
  399.   {
  400.     case TEX_RTF:
  401.     {
  402.       strcpy(extensionBuf, "rtf");
  403.       strcat(wildBuf, "rtf");
  404.       break;
  405.     }
  406.     case TEX_XLP:
  407.     {
  408.       strcpy(extensionBuf, "xlp");
  409.       strcat(wildBuf, "xlp");
  410.       break;
  411.     }
  412.     case TEX_HTML:
  413.     {
  414.       strcpy(extensionBuf, "html");
  415.       strcat(wildBuf, "html");
  416.       break;
  417.     }
  418.   }
  419.   if (force || !OutputFile)
  420.   {
  421.     char *s = wxFileSelector("Choose output file", path, FileNameFromPath(OutputFile),
  422.                    extensionBuf, wildBuf);
  423.     if (s)
  424.       OutputFile = copystring(s);
  425.   }
  426. }
  427.  
  428. Bool Go(void)
  429. {
  430.   ChooseInputFile();
  431.   ChooseOutputFile();
  432.   if (!InputFile || !OutputFile)
  433.     return FALSE;
  434.  
  435.   // Find extension-less filename
  436.   strcpy(FileRoot, OutputFile);
  437.   StripExtension(FileRoot);
  438.   sprintf(ContentsName, "%s.con", FileRoot);
  439.   sprintf(TmpContentsName, "%s.cn1", FileRoot);
  440.   sprintf(RefName, "%s.ref", FileRoot);
  441.  
  442.   if (FileExists(RefName))
  443.     ReadTexReferences(RefName);
  444.  
  445.   Bool success = FALSE;
  446.  
  447.   if (InputFile && OutputFile)
  448.   {
  449.     if (!FileExists(InputFile))
  450.     {
  451.       OnError("Cannot open input file!");
  452.       TexCleanUp();
  453.       return FALSE;
  454.     }
  455.  
  456.     OnInform("Reading LaTeX file...");
  457.     TexLoadFile(InputFile, MacroFile);
  458.  
  459.     switch (convertMode)
  460.     {
  461.       case TEX_RTF:
  462.       {
  463.         success = RTFGo();
  464.         break;
  465.       }
  466.       case TEX_XLP:
  467.       {
  468.         success = XLPGo();
  469.         break;
  470.       }
  471.       case TEX_HTML:
  472.       {
  473.         success = HTMLGo();
  474.         break;
  475.       }
  476.     }
  477.   }
  478.  
  479.   if (success)
  480.   {
  481.     WriteTexReferences(RefName);
  482.     TexCleanUp();
  483.     startedSections = FALSE;
  484.  
  485.     OnInform("Finished.");
  486.     return TRUE;
  487.   }
  488.  
  489.   TexCleanUp();
  490.   startedSections = FALSE;
  491.  
  492.   OnInform("Sorry, unsuccessful.");
  493.   return FALSE;
  494. }
  495.  
  496. void OnError(char *msg)
  497. {
  498.   if (isInteractive)
  499.     (*frame->textWindow) << "Error: " << msg << "\n";
  500.   else
  501. #ifdef wx_x
  502.     cerr << "Error: " << msg << "\n";
  503. #endif
  504. #ifdef wx_msw
  505.     wxError(msg);
  506. #endif
  507.   wxYield();
  508. }
  509.  
  510. void OnInform(char *msg)
  511. {
  512.   if (isInteractive)
  513.     (*frame->textWindow) << msg << "\n";
  514.   else
  515. #ifdef wx_x
  516.     cerr << msg << "\n";
  517. #endif
  518. #ifdef wx_msw
  519.     {}
  520. #endif
  521.   wxYield();
  522. }
  523.  
  524. void OnMacro(char *name, int no_args, Bool start)
  525. {
  526.   switch (convertMode)
  527.   {
  528.     case TEX_RTF:
  529.     {
  530.       RTFOnMacro(name, no_args, start);
  531.       break;
  532.     }
  533.     case TEX_XLP:
  534.     {
  535.       XLPOnMacro(name, no_args, start);
  536.       break;
  537.     }
  538.     case TEX_HTML:
  539.     {
  540.       HTMLOnMacro(name, no_args, start);
  541.       break;
  542.     }
  543.   }
  544. }
  545.  
  546. Bool OnArgument(char *name, int arg_no, Bool start)
  547. {
  548.   switch (convertMode)
  549.   {
  550.     case TEX_RTF:
  551.     {
  552.       return RTFOnArgument(name, arg_no, start);
  553.       break;
  554.     }
  555.     case TEX_XLP:
  556.     {
  557.       return XLPOnArgument(name, arg_no, start);
  558.       break;
  559.     }
  560.     case TEX_HTML:
  561.     {
  562.       return HTMLOnArgument(name, arg_no, start);
  563.       break;
  564.     }
  565.   }
  566.   return TRUE;
  567. }
  568.  
  569.